道路ネットワークは通常グラフとして扱われる。 グラフとは棒グラフとか折れ線グラフではなく、数学で扱われる用語である。 詳しくは「グラフ理論入門」(optimization/graph/graph.ipynb)を参照すること(この資料がグラフに関する資料であって道路ネットワークやVRP に関する資料でないため注意すること)。 また道路ネットワークデータの例として、ダミーの道路網データを optimization/road-network フォルダに置いてある。 研究で実際に使う道路ネットワークは購入データであり配布できないため、教材では同じファイル形式のダミーデータを使う。 形式の説明とデータの生成、networkx による基本操作は同フォルダの road_network.ipynb にまとめてある。 - nodes_ud.csv 道路ネットワークを構成するノード(主に交差点)のID および座標データになる。 データ構成は ノードID, 経度, 緯度 になる。 - links_ud.csv 道路ネットワークを構成するエッジ(ノードをつなぐ道路)データになる。 データ構成は 始点ノード, 終点ノード, 道路長 [m], 始点ノードの経度, 始点ノードの緯度, 終点ノードの経度, 終点ノードの緯度, 道路種別番号 になる。 道路種別番号は無視してもよい。 各行に始点ノードと終点ノードをつなぐエッジの情報が記載されている。 これらをVRP でどう扱うかを考える。 vehicle_routing_problem.ipynb の実装には # --- ノード座標の生成 --- # 座標: 配列 [ [x0, y0], [x1, y1], ... ] (0番がデポ) coords = np.random.uniform(low=coord_range[0], high=coord_range[1], size=(n_total, 2)) # --- ユークリッド距離行列の計算 --- dist_matrix = cdist(coords, coords) という部分がある。 このコードはランダムに座標を生成しているが、道路ネットワークで行うなら nodes_ud.csv を読み込み、coords を作成する必要がある。 またdist_matrix に関しても、現在はユークリッド距離(2点間の直線距離)で計算しているが、links_ud.csv には道路長が記載されているのでそれを使ったほうがいいだろう。 一般には各ノード間の距離は、Dijkstra 法といった最短経路探索手法を使って求める。 この実装はさすがに大変なので、例えば networkx といったPython 向けのライブラリがかなり有用である。 networkx の使い方についてはいろいろ情報があるので探してみること。 例えば https://scmopt.github.io/opt100/01graph.html が参考になるだろう。 この差し替えを実際に行った例は vehicle_routing_problem.ipynb の「道路ネットワーク上のVRP」の節にある。 まず自力で書き換えを試してから、答え合わせとして参照するとよい。